import { __private, _decorator, AudioClip, Collider2D, Enum, EventTouch, Input, input, instantiate, IPhysics2DContact, misc, Node, Prefab, sys, UITransform, Vec3, view } from 'cc';
import { MoveBaseEntity } from './MoveBaseEntity';
import { Reward, RewardType } from './Reward';
import { GameScene } from './GameScene';
import { L } from './tools/L';
import { AudioManager } from './tools/AudioManager';
const { ccclass, property } = _decorator;

export enum ShootType {
    OneBullet = "OneBullet", TwoBullet = "TwoBullet"
}
Enum(ShootType);

@ccclass('Player')
export class Player extends MoveBaseEntity {
    /**
     * 子弹的发射速率
     */
    @property
    shootRate: number = 0.5;
    @property(Prefab)
    bullet1Prefab: Prefab;
    @property(Node)
    bullet1Position: Node;

    @property(Prefab)
    bullet2Prefab: Prefab;
    @property(Node)
    bullet2LeftPosition: Node;
    @property(Node)
    bullet2RightPosition: Node;
    @property(Node)
    bulletParent: Node;

    @property({ type: ShootType })
    shootType: ShootType = ShootType.OneBullet;

    @property(AudioClip)
    bulletAudio: AudioClip | null = null;
    @property(AudioClip)
    gitBombRewardAudioClip: AudioClip | null = null;
    @property(AudioClip)
    gitDoubleShootRewardAudioClip: AudioClip | null = null;
    
    /**
     * 0 ~ shootRate 之间, 达到 shootRate 后就发射
     */
    shootTimer: number = 1;
    rewardTwoShootTimePeriod: number = 5; //奖励双发模式的持续时间(单位 s)

    protected onLoad(): void {
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }

    start() {
        super.start();
        GameScene.inst.life = this.hp;
    }

    protected onDestroy(): void {
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        super.onDestroy();
    }

    // FIXME: 坐标写死了, 需要优化
    onTouchMove(event: EventTouch) {
        if(GameScene.inst.isPaused()) return;
        
        // 1. 获取触摸点的 UI 坐标（基于左下角原点）
        const touchPos = event.getUILocation();

        // 2. 转换为节点父级的本地坐标系（Player 的父节点是 Canvas）
        const parentUITransform = this.node.parent.getComponent(UITransform);
        const localPos = parentUITransform.convertToNodeSpaceAR(new Vec3(touchPos.x, touchPos.y, 0));

        // 3. 边界检查（限制移动范围）
        const visibleSize = view.getVisibleSize();
        const nodeSize = this.node.getComponent(UITransform).contentSize;

        const minX = -visibleSize.width / 2 + nodeSize.width / 2;
        const maxX = visibleSize.width / 2 - nodeSize.width / 2;
        const minY = -visibleSize.height / 2 + nodeSize.height / 2;
        const maxY = visibleSize.height / 2 - nodeSize.height / 2;

        localPos.x = misc.clampf(localPos.x, minX, maxX);
        localPos.y = misc.clampf(localPos.y, minY, maxY);

        // 4. 直接设置节点位置（或使用缓动）
        this.node.setPosition(localPos);
        
        //  // 计算当前帧移动速度（像素/秒，假设60FPS）
        // const deltaX = event.getDeltaX();
        // const deltaY = event.getDeltaY();
        // const speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 60; // 乘以60估算秒级速度

        // // 动态调整系数（速度越快，系数越小）
        // let speedFactor = 1;
        // L.debug('sys.platform===' + sys.platform)
        // if(sys.platform === sys.Platform.WECHAT_GAME || sys.platform === sys.Platform.MACOS) {
        //     const _minSpeedFactor: number = 0.75;  // 快速移动时的最小系数
        //     const _maxSpeedFactor: number = 0.85;  // 慢速移动时的最大系数
        //     speedFactor = Math.max(
        //         _minSpeedFactor,
        //         _maxSpeedFactor - speed * 0.0005 // 调整0.0005控制下降曲线
        //     );
        // }

        // // 1. 实时获取当前屏幕和节点数据
        // const visibleSize = view.getVisibleSize();
        // const nodeSize = this.node.getComponent(UITransform).contentSize;
        
        // // 2. 实时计算边界
        // const minX = -visibleSize.width / 2 + nodeSize.width / 2;
        // const maxX = visibleSize.width / 2 - nodeSize.width / 2;
        // const minY = -visibleSize.height / 2 + nodeSize.height / 2;
        // const maxY = visibleSize.height / 2 - nodeSize.height / 2;

        // const movePos = new Vec3(
        //     this.node.position.x + event.getDeltaX() * speedFactor,
        //     this.node.position.y + event.getDeltaY() * speedFactor,
        //     this.node.position.z
        // );
        
        // movePos.x = misc.clampf(movePos.x, minX, maxX);
        // movePos.y = misc.clampf(movePos.y, minY, maxY);
        
        // this.node.setPosition(movePos);
    }

    protected hpChanged(): void {
        GameScene.inst.life = this.hp;
    }

    update(dt: number) {
        this.shootTimer += dt;
        if (this.shootTimer >= this.shootRate) {
            this.shootTimer = 0;

            if (this.shootType == ShootType.OneBullet) {
                const bullet = instantiate(this.bullet1Prefab);
                this.bulletParent.addChild(bullet);

                bullet.setWorldPosition(this.bullet1Position.worldPosition);
                AudioManager.inst.playOneShot(this.bulletAudio);
            } else if (this.shootType == ShootType.TwoBullet) {
                const leftBullet = instantiate(this.bullet2Prefab);
                const rightBullet = instantiate(this.bullet2Prefab);
                this.bulletParent.addChild(leftBullet);
                this.bulletParent.addChild(rightBullet);

                leftBullet.setWorldPosition(this.bullet2LeftPosition.worldPosition);
                rightBullet.setWorldPosition(this.bullet2RightPosition.worldPosition);
                AudioManager.inst.playOneShot(this.bulletAudio);
            }
        }

        super.update(dt);
    }

    cb = () => this.shootType = ShootType.OneBullet;
    //重载父类的方法
    protected checkPreBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null): boolean {
        const reward = otherCollider.getComponent(Reward);

        if(reward) { // 与奖励类碰撞 
            L.log(`[奖励]类型[ ${reward.rewardType} ]`);
            if(reward.rewardType == RewardType.Bomb) {
                GameScene.inst.addBomb(1);
                AudioManager.inst.playOneShot(this.gitBombRewardAudioClip);
            } else if(reward.rewardType == RewardType.TwoShoot) {
                AudioManager.inst.playOneShot(this.gitDoubleShootRewardAudioClip);
                this.shootType = ShootType.TwoBullet;
                this.unschedule(this.cb)
                this.scheduleOnce(this.cb, this.rewardTwoShootTimePeriod);
            }
        }

        return ! reward;
    }

    dead(dt: number): boolean {
        const flag = super.dead(dt);
        if(flag) {
            this.scheduleOnce(() => GameScene.inst.gameOver(), dt);
        }

        return flag;
    }
}

